from base.vertice import Vertice
from base.graph import Graph
from dijkstra import Dijkstra

class Weight:
    def __init__(self, time, distance):
            self.time = time
            self.distance = distance
    def __add__(self, other):
            return Weight(self.time + other.time, self.distance + other.distance)
    def __lt__(self, other):
            return self.time < other.time if self.time != other.time else self.distance < other.distance 
    def __repr__(self):
            return '('+str(self.time)+','+str(self.distance)+')'

w = dict()  # dicionario dos pesos das arestas, associa um peso a cada aresta
# peso: (t - tempo, d - distancia)

def extract_weight(pair):
    if pair in w:
        return w[pair]

vertices = [
            Vertice(1),
            Vertice(2),
            Vertice(3),
            Vertice(4),
            Vertice(5),
            ]

g = Graph(vertices)

# adicionando arestas entre os vertices do grafo

# adjacencias 1:

g.add_edge(vertices[0], vertices[1])
w[(vertices[0], vertices[1])] = Weight(3, 8)
g.add_edge(vertices[0], vertices[2])
w[(vertices[0], vertices[2])] = Weight(10, 4)
g.add_edge(vertices[0], vertices[3])
w[(vertices[0], vertices[3])] = Weight(2,5)

# adjacencias 2:
g.add_edge(vertices[1], vertices[4])
w[(vertices[1], vertices[4])] = Weight(5,9)

# adjacencias 3:
g.add_edge(vertices[2], vertices[3])
w[(vertices[2], vertices[3])] = Weight(4,1)

# adjacencias 4:
g.add_edge(vertices[3], vertices[2])
w[(vertices[3], vertices[2])] = Weight(7,5)
g.add_edge(vertices[3], vertices[1])
w[(vertices[3], vertices[1])] = Weight(8,3)
g.add_edge(vertices[3], vertices[4])
w[(vertices[3], vertices[4])] = Weight(7,2)

print('Menor caminho usando dijkstra entre a origem e o destino:')

path = ''
result_set = Dijkstra(Weight(0,0), Weight(float('inf'),float('inf'))).dijkstra(g, extract_weight, vertices[0])    
for v in result_set[vertices[4]][::-1]:
    path += str(v.name) + ', '

print(path)
print('Custo: ', vertices[4].key)